﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace FreeDream.Common
{
    public static class EnumHelper
    {
        ///// <summary>
        ///// 获取枚举描述
        ///// </summary>
        ///// <param name="value"></param>
        ///// <returns></returns>
        //public static string GetDescription(this Enum value)
        //{
        //    var type = value.GetType();
        //    var name = Enum.GetName(type, value);
        //    if (string.IsNullOrWhiteSpace(name))
        //        return value.ToString();
        //    var field = type.GetField(name);
        //    var des = field?.GetCustomAttribute<DescriptionAttribute>();
        //    if (des == null)
        //        return value.ToString();
        //    return des.Description;
        //}

        ///// <summary>
        ///// 获取枚举类子项描述信息
        ///// </summary>
        ///// <param name="enumSubitem">枚举类子项</param>        
        //public static string GetEnumDescription(Enum enumSubitem)
        //{
        //    string strValue = enumSubitem.ToString();
        //    FieldInfo fieldinfo = enumSubitem.GetType().GetField(strValue);
        //    Object[] objs = fieldinfo.GetCustomAttributes(typeof(DescriptionAttribute), false);
        //    if (objs == null || objs.Length == 0)
        //    {
        //        return strValue;
        //    }

        //    DescriptionAttribute da = (DescriptionAttribute)objs[0];
        //    return da.Description;
        //}

        /// <summary>
        /// 枚举转字典项
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="keyDefault"></param>
        /// <param name="valueDefault"></param>
        /// <returns></returns>
        public static Dictionary<int, string> EnumToDictionary<T>(int? keyDefault, string valueDefault = "")
        {

            Dictionary<int, string> dicEnum = new Dictionary<int, string>();
            Type enumType = typeof(T);
            if (!enumType.IsEnum)
            {
                return dicEnum;
            }
            if (keyDefault != null) //判断是否添加默认选项
            {
                dicEnum.Add((int)keyDefault, valueDefault);
            }
            string[] fieldstrs = Enum.GetNames(enumType); //获取枚举字段数组
            foreach (var item in fieldstrs)
            {
                string description = string.Empty;
                var field = enumType.GetField(item);
                object[] arr = field.GetCustomAttributes(typeof(DescriptionAttribute), true); //获取属性字段数组
                if (arr != null && arr.Length > 0)
                {
                    description = ((DescriptionAttribute)arr[0]).Description;   //属性描述
                }
                else
                {
                    description = item;  //描述不存在取字段名称
                }
                dicEnum.Add((int)Enum.Parse(enumType, item), description);  //不用枚举的value值作为字典key值的原因从枚举例子能看出来，其实这边应该判断他的值不存在，默认取字段名称
            }
            return dicEnum;
        }

        /// <summary>
        /// 根据枚举的值，获取枚举值的描述信息
        /// </summary>
        /// <param name="value">要获取描述信息的枚举值。</param>
        /// <returns>枚举值的描述信息。</returns>
        public static string GetEnumDesc<T>(int value)
        {
            Type enumType = typeof(T);
            DescriptionAttribute attr = null;

            // 获取枚举常数名称。
            string name = Enum.GetName(enumType, value);
            if (name != null)
            {
                // 获取枚举字段。
                FieldInfo fieldInfo = enumType.GetField(name);
                if (fieldInfo != null)
                {
                    // 获取描述的属性。
                    attr = Attribute.GetCustomAttribute(fieldInfo, typeof(DescriptionAttribute), false) as DescriptionAttribute;
                }
            }

            // 返回结果
            if (attr != null && !string.IsNullOrEmpty(attr.Description))
                return attr.Description;
            else
                return string.Empty;
        }
        /// <summary>
        /// 根据值,获取描述
        /// </summary>
        /// <param name="e"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public static string GetEnumDesc(Type e, int? value)
        {
            FieldInfo[] fields = e.GetFields();
            for (int i = 1, count = fields.Length; i < count; i++)
            {
                if ((int)Enum.Parse(e, fields[i].Name) == value)
                {
                    DescriptionAttribute[] EnumAttributes = (DescriptionAttribute[])fields[i].
                        GetCustomAttributes(typeof(DescriptionAttribute), false);
                    if (EnumAttributes.Length > 0)
                    {
                        return EnumAttributes[0].Description;
                    }
                }
            }
            return "";
        }

        /// <summary>
        /// 根据值，获取名称
        /// </summary>
        /// <param name="enumValue">传入的值必须是枚举的枚举基或基础类型，如 Int32。</param>
        /// <returns></returns>
        public static string GetEnumName<T>(Enum enumValue)
        {
            return Enum.GetName(typeof(T), enumValue);
        }

        /// <summary>
        ///  根据值，获取名称
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="enumValue"></param>
        /// <returns></returns>
        public static string GetEnumName<T>(object enumValue)
        {
            return Enum.GetName(typeof(T), enumValue);
        }

        /// <summary>
        /// 根据值，获取描述
        /// </summary>
        /// <param name="enumValue"></param>
        /// <returns></returns>
        public static string GetEnumDescription(Enum enumValue)
        {
            string value = enumValue.ToString();
            FieldInfo field = enumValue.GetType().GetField(value);
            object[] objs = field.GetCustomAttributes(typeof(DescriptionAttribute), false);    //获取描述属性
            if (objs == null || objs.Length == 0)
                return value;
            DescriptionAttribute descriptionAttribute = (DescriptionAttribute)objs[0];
            return descriptionAttribute.Description;
        }

        /// <summary>
        /// 获取所有
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static SortedList<int, string> GetItems<T>()
        {
            var result = new SortedList<int, string>();
            Type t = typeof(T);
            Array arrays = Enum.GetValues(t);
            for (int i = 0; i < arrays.LongLength; i++)
            {
                object test = arrays.GetValue(i);
                FieldInfo fieldInfo = test.GetType().GetField(test.ToString());
                object[] attribArray = fieldInfo.GetCustomAttributes(false);
                DescriptionAttribute attrib = (DescriptionAttribute)attribArray[0];
                result.Add(Convert.ToInt32(test), attrib.Description);
            }
            return result;
        }

        /// <summary>
        /// 扩展方法，获得枚举的Description
        /// </summary>
        /// <param name="value">枚举值</param>
        /// <param name="nameInstead">当枚举值没有定义DescriptionAttribute，是否使用枚举名代替，默认是使用</param>
        /// <returns>枚举的Description</returns>
        public static string GetDescription(this Enum value, Boolean nameInstead = true)
        {
            Type type = value.GetType();
            string name = Enum.GetName(type, value);
            if (name == null)
            {
                return null;
            }

            FieldInfo field = type.GetField(name);
            DescriptionAttribute attribute = System.Attribute.GetCustomAttribute(field, typeof(DescriptionAttribute)) as DescriptionAttribute;

            if (attribute == null && nameInstead == true)
            {
                return name;
            }
            return attribute?.Description;
        }

    }
}
